#include "KSADAnalyzeVis.hh"
#include "KSADAnalyze.hh"
#include "TCanvas.h"
#include "TH3.h"
#include <sstream>
#include "KSADGlobals.hh"
#include "TColor.h"
#include "TView.h"
#include "TApplication.h"
#include "KSADAnalyzeEvent.hh"
#include "TLine.h"
#include "TText.h"
#include "TLatex.h"
#include "TPolyLine3D.h"

void TCanvas::Closed()
{
	Emit("Closed()");

	gApplication->Terminate(0);
}

KSADAnalyzeVis::KSADAnalyzeVis(KSADAnalyze* newAnalyze)
{
	analyze = newAnalyze;
	eventList = analyze->GetEventList();
	numEvents = analyze->GetNumEvents();

	draw();
}

KSADAnalyzeVis::~KSADAnalyzeVis()
{
	;
}

void KSADAnalyzeVis::draw()
{
	TCanvas* c1 = new TCanvas("Visualization of data analysis","Visualization of data analysis",1100,900);
	(void)c1;
	TPad*	 p1 = new TPad("crystal","crystal",0.,0.5,1.,1,13,1,1);
	TPad*	 p2 = new TPad("lineProjection","lineProjection",0.,0.,0.5,0.5,13,1,0);
	TPad*	 p3 = new TPad("legend","legend",0.5,0.,1.,0.5,13,1,0);	
	p1->Draw(); p2->Draw(); p3->Draw();

	p1->cd();
	TView* view = TView::CreateView();
	view->SetPerspective();
	view->SetRange(-0.6,-0.6,-1,0.6,0.6,0.5);

	TH3D* h3 = analyze->GetH3();		
	int crystalDimension = 1.2*m/crystalSize;
	double maxValue = analyze->GetMaxValue();
	int tBins = h3->GetNbinsZ();
	double timeWeightMax = .75/double(tBins);


	for(int t = 0 ; t<tBins+1 ; t++)
	{
		for(int i = 0 ; i<crystalDimension ; i++)
		{
			for(int j = 0 ; j<crystalDimension ; j++)
			{
				double xPos = -0.6 + (i+0.5)*crystalSize/m; double yPos = -0.6 + (j+0.5)*crystalSize/m;
				double tPos = (-t-0.5)*timeWeightMax;

				double energy = (h3->GetBinContent(i+1,j+1,t+1));
				double weight = pow(energy/maxValue,1./2.)*crystalSize/2/m;
				double timeWeight = pow(energy/maxValue,1)*timeWeightMax/4;

				if(energy > 0) DrawCube(xPos,yPos,tPos,weight,timeWeight,0);
			}
		}
	}

	for(int e = 0 ; e<numEvents; e++)
	{
		TH3D* eventH3 = eventList[e]->GetH3();
		int eventDimensionX = eventH3->GetNbinsX();
		int eventDimensionY = eventH3->GetNbinsY();
		int eventDimensionZ = eventH3->GetNbinsZ();
		bool isPossible = eventList[e]->IsPossible();
		double xHistPos = eventList[e]->GetLeftX()/m;
		double yHistPos = eventList[e]->GetBottomY()/m;
		double tStart	= eventList[e]->GetStartTime()/timeRes;
		int color = kYellow;

		if(isPossible) color = kGreen-9;
		else color = kRed-9;

		for(int t = 0 ; t<eventDimensionZ ; t++)
		{
			for(int i = 0 ; i<eventDimensionX ; i++)
			{
				for(int j = 0 ; j<eventDimensionY ; j++)
				{
					double eventXPos = xHistPos+(i+0.5)*crystalSize/m;
					double eventYPos = yHistPos+(j+0.5)*crystalSize/m;
					double eventTPos = (-tStart+(-t-0.5))*timeWeightMax;

					double eventEnergy = (eventH3->GetBinContent(i+1,j+1,t+1))*MeV;
					double spaceWeight = pow(eventEnergy/maxValue,1./2.)*crystalSize/2/m;
					double timeWeight = pow(eventEnergy/maxValue,1)*timeWeightMax/4;

					if(eventEnergy > 0) DrawCube(eventXPos,eventYPos,eventTPos,spaceWeight,timeWeight,color);
				}
			}
		}
	}

/*	for(int e = 0 ; e<numEvents ; e++)
	{
		double max = 0;
		double x = 0;
		double y = 0;
		double xHistPos = eventList[e]->GetLeftX()/m;
		double yHistPos = eventList[e]->GetBottomY()/m;
		double tStart = eventList[e]->GetStartTime()/timeRes;
		for(int t = 0 ; t<tBins ; t++)
		{
			if(analyze->GetCoEAtTime(x,y,t,e)>max)
			{
				max = analyze->GetCoEAtTime(x,y,t,e);
			}
			else {;}
		}
		for(int t = 0 ; t<tBins ; t++)
		{
			double time = (-tStart-(t+0.5))*crystalSize/m;
			double energy = analyze->GetCoEAtTime(x,y,t,e);
			DrawCube(xHistPos+x/m,yHistPos+y/m,time,energy/max*crystalSize/2/m,1);
		}
	}
*/	BoundDrawer(tBins);
		
	//Draw projections for every event on top pad

	for(int i = 0 ; i<numEvents ; i++)
	{
//		Cone(i,0.25);
	}
	
	p2->cd();
	LineDrawer();
	
	p3->cd();
	Legend();

	p2->SetEditable(false);
	p3->SetEditable(false);

	gApplication->Run(true);
}

void KSADAnalyzeVis::BoundDrawer(int bins)
{
	double height = bins*crystalSize/m;
	(void)height;
	DrawSquare(0,0,0,0.6,0);	
//	DrawSquare(0,0,-height,0.6,0);	
	DrawSquare(0,0,0,0.1,0);
//	DrawSquare(0,0,-height,0.1,0);

	double* xOne = new double[2];
	double* yOne = new double[2];
	double* xTwo = new double[2];
	double* yTwo = new double[2];
	double* xThree = new double[2];
	double* yThree = new double[2];
	double* xFour = new double[2];
	double* yFour = new double[2];
	double* xFive = new double[2];
	double* yFive = new double[2];
	double* xSix = new double[2];
	double* ySix = new double[2];
	double* xSeven = new double[2];
	double* ySeven = new double[2];
	double* xEight = new double[2];
	double* yEight = new double[2];
//	double* z = new double[2];

	xOne[0]=-.6; xOne[1]=xOne[0];
	yOne[0]=-.6; yOne[1]=yOne[0];
	xTwo[0]=.6;xTwo[1]=xTwo[0];
	yTwo[0]=-.6;yTwo[1]=yTwo[0];
	xThree[0]=.6;xThree[1]=xThree[0];
	yThree[0]=.6;yThree[1]=yThree[0];
	xFour[0]=-.6;xFour[1]=xFour[0];
	yFour[0]=.6;yFour[1]=yFour[0];

	xFive[0]=-.1;xFive[1]=xFive[0];
	yFive[0]=-.1;yFive[1]=yFive[0];
	xSix[0]=.1;xSix[1]=xSix[0];
	ySix[0]=-.1;ySix[1]=ySix[0];
	xSeven[0]=.1;xSeven[1]=xSeven[0];
	ySeven[0]=.1;ySeven[1]=ySeven[0];
	xEight[0]=-.1;xEight[1]=xEight[0];
	yEight[0]=.1;yEight[1]=yEight[0];
}
														
void KSADAnalyzeVis::DrawSquare(double x,double y,double z,double length,int color)
{
	double* xList = new double[5];
	double* yList = new double[5];
	double* zList = new double[5];
	for(int i = 0; i<5 ; i++) zList[i]=z;
	xList[0]=x-length; xList[1]=x+length; xList[2]=x+length; xList[3]=x-length; xList[4]=x-length;
	yList[0]=y-length; yList[1]=y-length; yList[2]=y+length; yList[3]=y+length; yList[4]=y-length;
	TPolyLine3D* square	=	new TPolyLine3D(5,xList,yList,zList);
	square->SetLineColor(color);
	square->Draw();
}

void KSADAnalyzeVis::DrawCube(double x,double y,double z,double length,double time,int color)
{
	double* xOne = new double[2];
	double* yOne = new double[2];
	double* zList = new double[2];
	double* xTwo = new double[2];
	double* yTwo = new double[2];
	double* xThree = new double[2];
	double* yThree = new double[2];
	double* xFour = new double[2];
	double* yFour = new double[2];

	xOne[0]=x-length; xOne[1]=xOne[0];
	yOne[0]=y-length; yOne[1]=yOne[0];
	xTwo[0]=x+length; xTwo[1]=xTwo[0];
	yTwo[0]=y-length; yTwo[1]=yTwo[0];
	xThree[0]=x+length; xThree[1]=xThree[0];
	yThree[0]=y+length; yThree[1]=yThree[0];
	xFour[0]=x-length; xFour[1]=xFour[0];
	yFour[0]=y+length; yFour[1]=yFour[0];
	zList[0]=z-time; zList[1]=z+time;

	DrawSquare(x,y,z+time,length,color);
	DrawSquare(x,y,z-time,length,color);

	TPolyLine3D* one = new TPolyLine3D(2,xOne,yOne,zList);
	TPolyLine3D* two = new TPolyLine3D(2,xTwo,yTwo,zList);
	TPolyLine3D* three = new TPolyLine3D(2,xThree,yThree,zList);
	TPolyLine3D* four = new TPolyLine3D(2,xFour,yFour,zList);
	one->SetLineColor(color);
	two->SetLineColor(color);
	three->SetLineColor(color);
	four->SetLineColor(color);
	one->Draw();
	two->Draw();
	three->Draw();
	four->Draw();


}

void KSADAnalyzeVis::Cone(int event,double radius)
{
	double x		=	eventList[event]->GetXPos()/m;
	double y		=	eventList[event]->GetYPos()/m;
	double azimuthalLow	=	eventList[event]->GetAzimuthalLow()+180*deg;		//angles are altered to represents back projections
	double azimuthalHigh	=	eventList[event]->GetAzimuthalHigh()+180*deg;
	double polarHigh	=	eventList[event]->GetPolarHigh()-2*(eventList[event]->GetPolarHigh()-90*deg);	//polarHigh is a low number which
	double polarLow		=	eventList[event]->GetPolarLow()-2*(eventList[event]->GetPolarLow()-90*deg);	//projects a high z value. Opposite for polarLow.
	double azimuthalGuess	=	eventList[event]->GetAzimuthalAngle()-180*deg;
	double polarGuess	=	45*deg; //eventList[event]->GetPolarAngle()-2*(eventList[event]->GetPolarAngle()-90*deg);

	while(azimuthalLow>360*deg)
	{
		azimuthalLow-=360*deg;
		azimuthalHigh-=360*deg;
	}

	double* xBottomLegs	=	new double[3];
	double* yBottomLegs	=	new double[3];
	double* zBottomLegs	=	new double[3];
	xBottomLegs[0]=x+radius*cos(azimuthalLow/radian)*sin(polarLow/radian); xBottomLegs[1]=x; xBottomLegs[2]=x+radius*cos(azimuthalHigh/radian)*sin(polarLow/radian);
	yBottomLegs[0]=y+radius*sin(azimuthalLow/radian)*sin(polarLow/radian); yBottomLegs[1]=y; yBottomLegs[2]=y+radius*sin(azimuthalHigh/radian)*sin(polarLow/radian);
	zBottomLegs[0]=radius*cos(polarLow/radian); zBottomLegs[1]=0; zBottomLegs[2]=zBottomLegs[0];
	TPolyLine3D* bottomLegs	=	new TPolyLine3D(3,xBottomLegs,yBottomLegs,zBottomLegs);
	bottomLegs->SetLineColor(event+2);
	bottomLegs->Draw();

	double* xTopLegs	=	new double[3];
	double* yTopLegs	=	new double[3];
	double* zTopLegs	=	new double[3];
	xTopLegs[0]=x+radius*cos(azimuthalLow/radian)*sin(polarHigh/radian); xTopLegs[1]=x; xTopLegs[2]=x+radius*cos(azimuthalHigh/radian)*sin(polarHigh/radian);
	yTopLegs[0]=y+radius*sin(azimuthalLow/radian)*sin(polarHigh/radian); yTopLegs[1]=y; yTopLegs[2]=y+radius*sin(azimuthalHigh/radian)*sin(polarHigh/radian);
	zTopLegs[0]=radius*cos(polarHigh/radian); zTopLegs[1]=0; zTopLegs[2]=zTopLegs[0];
	TPolyLine3D* topLegs =       new TPolyLine3D(3,xTopLegs,yTopLegs,zTopLegs);
	topLegs->SetLineColor(event+2);
	topLegs->Draw();

//	double* xThirdLeg	=	new double[3];
//	double* yThirdLeg	=	new double[3];
//	double* zThirdLeg	=	new double[3];
//	xThirdLeg[0]=x+radius*cos(azimuthalGuess/radian)*sin(polarLow/radian); xThirdLeg[1]=x; xThirdLeg[2]=x+radius*cos(azimuthalGuess/radian)*sin(polarHigh/radian);
//	yThirdLeg[0]=y+radius*sin(azimuthalGuess/radian)*sin(polarLow/radian); yThirdLeg[1]=y; yThirdLeg[2]=y+radius*sin(azimuthalGuess/radian)*sin(polarHigh/radian);
//	zThirdLeg[0]=radius*cos(polarLow/radian); zThirdLeg[1]=0; zThirdLeg[2]=radius*cos(polarHigh/radian);
//	TPolyLine3D* thirdLeg 	=	new TPolyLine3D(3,xThirdLeg,yThirdLeg,zThirdLeg);
//	thirdLeg->SetLineColor(event+2);
//	thirdLeg->Draw();

	int numAzSegs	=	radius*(azimuthalHigh-azimuthalLow)/radian/.01+1;
	int numPolSegs	=	radius*(polarLow-polarHigh)/radian/.01+1;
	double dPhi	=	(azimuthalHigh-azimuthalLow)/numAzSegs;
	double dTheta	=	(polarLow-polarHigh)/numPolSegs;
	double* xPolLow	=	new double[numPolSegs+1];
	double* xPolHigh=	new double[numPolSegs+1];
	double* xPolThird=	new double[numPolSegs+1];
	double* yPolLow	=	new double[numPolSegs+1];
	double* yPolHigh=	new double[numPolSegs+1];
	double* yPolThird=	new double[numPolSegs+1];
	double* zPol	=	new double[numPolSegs+1];
	for(int i = 0 ; i<numPolSegs+1 ; i++)
	{
		double loopAngle = polarLow-i*dTheta;
		xPolLow[i]=x+radius*cos(azimuthalLow/radian)*sin(loopAngle/radian);
		xPolHigh[i]=x+radius*cos(azimuthalHigh/radian)*sin(loopAngle/radian);
		xPolThird[i]=x+radius*cos(azimuthalGuess/radian)*sin(loopAngle/radian);
		yPolLow[i]=y+radius*sin(azimuthalLow/radian)*sin(loopAngle/radian);
		yPolHigh[i]=y+radius*sin(azimuthalHigh/radian)*sin(loopAngle/radian);
		yPolThird[i]=y+radius*sin(azimuthalGuess/radian)*sin(loopAngle/radian);
		zPol[i]=radius*cos(loopAngle/radian);
	}
	TPolyLine3D* polLow	=	new TPolyLine3D(numPolSegs+1,xPolLow,yPolLow,zPol);
	TPolyLine3D* polHigh	=	new TPolyLine3D(numPolSegs+1,xPolHigh,yPolHigh,zPol);
	TPolyLine3D* polThird	=	new TPolyLine3D(numPolSegs+1,xPolThird,yPolThird,zPol);
	polLow->SetLineColor(event+2);
	polHigh->SetLineColor(event+2);
	polThird->SetLineColor(event+2);
	polLow->Draw();
	polHigh->Draw();
	polThird->Draw();

	double* xAzLow	=	new double[numAzSegs+1];
	double* xAzHigh	=	new double[numAzSegs+1];
	double* xAzThird=	new double[numAzSegs+1];
	double* yAzLow	=	new double[numAzSegs+1];
	double* yAzHigh	=	new double[numAzSegs+1];
	double* yAzThird=	new double[numAzSegs+1];
	double* zAzLow	=	new double[numAzSegs+1];
	double* zAzHigh	=	new double[numAzSegs+1];
	double* zAzThird=	new double[numAzSegs+1];
	for(int i = 0 ; i<numAzSegs+1 ; i++)
	{
		double loopAngle = azimuthalLow+i*dPhi;
		xAzLow[i]=x+radius*cos(loopAngle/radian)*sin(polarLow/radian);
		xAzHigh[i]=x+radius*cos(loopAngle/radian)*sin(polarHigh/radian);
		xAzThird[i]=x+radius*cos(loopAngle/radian)*sin(polarGuess/radian);
		yAzLow[i]=y+radius*sin(loopAngle/radian)*sin(polarLow/radian);
		yAzHigh[i]=y+radius*sin(loopAngle/radian)*sin(polarHigh/radian);
		yAzThird[i]=y+radius*sin(loopAngle/radian)*sin(polarGuess/radian);
		zAzLow[i]=radius*cos(polarLow/radian);
		zAzHigh[i]=radius*cos(polarHigh/radian);
		zAzThird[i]=radius*cos(polarGuess/radian);
	}
	TPolyLine3D* azLow	=	new TPolyLine3D(numAzSegs+1,xAzLow,yAzLow,zAzLow);
	TPolyLine3D* azHigh	=	new TPolyLine3D(numAzSegs+1,xAzHigh,yAzHigh,zAzHigh);
	TPolyLine3D* azThird	=	new TPolyLine3D(numAzSegs+1,xAzThird,yAzThird,zAzThird);
	azLow->SetLineColor(event+2);
	azHigh->SetLineColor(event+2);
	azThird->SetLineColor(event+2);
	azLow->Draw();
	azHigh->Draw();
	azThird->Draw();
}	

void KSADAnalyzeVis::LineDrawer()
{

	double lineSpacing	=	1./(numEvents+2);
	
	double windowLow	=	1.15;
	double windowHigh	=	2.75;
	double windowLength	=	windowHigh-windowLow;

	double** position	=	new double*[numEvents];

	for(int i = 0 ; i<numEvents ; i++)
	{
		position[i]	=	new double[2];
		position[i][0]	=	0;		//position[i][0] is the i'th event zLow
		position[i][1]	=	0;		//position[i][1] represents zHigh

		double xStartPos	=	(eventList[i]->GetXPos())/m;
		double yStartPos	=	(eventList[i]->GetYPos())/m;		
		double polarLow		=	(eventList[i]->GetPolarLow())-2*(eventList[i]->GetPolarLow()-90*deg);
		double polarHigh	=	(eventList[i]->GetPolarHigh())-2*(eventList[i]->GetPolarHigh()-90*deg);
		
		if(eventList[i]->IsPossible())		//analyze class already tests to see if the event is a possible intersection with beam line.
		{
			double zHigh = sqrt(xStartPos*xStartPos+yStartPos*yStartPos)*tan(pi/2-polarHigh/radian);
			double zLow = sqrt(xStartPos*xStartPos+yStartPos*yStartPos)*tan(pi/2-polarLow/radian);
			if(zLow<windowLow && zHigh>windowHigh)
			{
				position[i][0]	=	0;
				position[i][1]	=	1;
			}
			else if(zLow<windowLow && zHigh<windowHigh && zHigh>windowLow)
			{
				position[i][0]	=	0;
				position[i][1]	=	(zHigh-windowLow)/windowLength;
			}
			else if(zLow>windowLow && zHigh<windowHigh)
			{
				position[i][0]	=	(zLow-windowLow)/windowLength;
				position[i][1]	=	(zHigh-windowLow)/windowLength;
			}
			else if(zLow<windowHigh && zHigh>windowHigh && zLow>windowLow)
			{
				position[i][0]	=	(zLow-windowLow)/windowLength;
				position[i][1]	=	1;
			}
		}										
	}
	
	double currentPos	=	0;
	double nextPos		=	1;
	bool test		=	true;
	int count		=	0;
	TLine* line		=	0;

	while(test)
	{
		for(int i = 0 ; i<numEvents ; i++)
		{
			if(position[i][0]>currentPos && position[i][0]<nextPos)
			{
				nextPos	=	position[i][0];
			}
			else if(position[i][0] == currentPos)
				{count++;}
			if(position[i][1]>currentPos && position[i][1]<nextPos)
			{
				nextPos	=	position[i][1];
			}
			else if(position[i][1] == currentPos)
				{count--;}
		}

		if(nextPos == currentPos)
		{
			if(currentPos != 1)
			{
				line	=	new TLine(lineSpacing,currentPos,lineSpacing,1);
				line->SetLineColor(0);
				line->Draw();
				test	=	false;
				break;
			}
			else
			{
				test	=	false;
				break;
			}
		}

		line	=	new TLine(lineSpacing,currentPos,lineSpacing,nextPos);

		switch(count)
		{
			case 0:
				line->SetLineColor(0);
				line->SetLineStyle(2);
				line->Draw();
				break;

			case 1:
				line->SetLineColor(kRed);
				line->Draw();
				break;

			case 2:
				line->SetLineColor(kGreen);
				line->Draw();
				break;

			default:
				line->SetLineColor(kBlue);
				line->Draw();
				break;
		}

		currentPos	=	nextPos;
		nextPos		=	1;
	}

	for(int i = 0 ; i<numEvents ; i++)
	{
		if(position[i][0] == 0 && position[i][1] == 0)
		{
			double xPos	=	lineSpacing*2 + lineSpacing*i;
			TLine* eventLine=	new TLine(xPos,0,xPos,1);
			eventLine->SetLineStyle(2);
			eventLine->SetLineColor(0);
			eventLine->Draw();
		}
		else
		{
			double xPos		=	lineSpacing*2 + lineSpacing*i;
			TLine* eventLine	=	new TLine(xPos,position[i][0],xPos,position[i][1]);
			eventLine->SetLineColor(i+2);
			eventLine->Draw();
			if(position[i][0]>0)
			{
				TLine* eventFillerLow	=	new TLine(xPos,0,xPos,position[i][0]);
				eventFillerLow->SetLineStyle(2);
				eventFillerLow->SetLineColor(0);
				eventFillerLow->Draw();
			}
			if(position[i][1]<1)
			{
				TLine* eventFillerHigh	=	new TLine(xPos,position[i][1],xPos,1);
				eventFillerHigh->SetLineStyle(2);
				eventFillerHigh->SetLineColor(0);
				eventFillerHigh->Draw();
			}
		}
	}
	
	for(int i = 0;i < numEvents;i++) delete position[i];
	delete position;

	for(int i = 0 ; i<5 ; i++)
	{
		TLine* scale	=	new TLine(0,0.25*i,.02,0.25*i);
		scale->SetLineColor(0);
		scale->Draw();
		std::stringstream stringStream;
		stringStream << windowLow+0.25*i*windowLength;
		G4String textString = stringStream.str();
		TText* scaleText	=	0;
		if(i == 4)
		{
			scaleText	=	new TText(0.0,0.25*i-.02-.005,textString);
		}
		else
		{
			scaleText	=	new TText(0.0,0.25*i+.005,textString);
		}
		scaleText->SetTextColor(0);
		scaleText->SetTextSize(.02);
		scaleText->Draw();
	}
	
	TText* fullProjection		=	new TText(lineSpacing-.02,0.04,"Projection of Events on Beam Line");
	TText* fullProjectionCont	=	new TText(lineSpacing+.03,0.04,"# of intersections: Red = 1; Green = 2; Blue > 2");
	fullProjection->SetTextAngle(90);
	fullProjectionCont->SetTextAngle(90);
	fullProjection->SetTextColor(0);
	fullProjectionCont->SetTextColor(0);
	fullProjection->SetTextSize(.03);
	fullProjectionCont->SetTextSize(.03);
	fullProjection->Draw();
	fullProjectionCont->Draw();
	
	for(int i = 0 ; i<numEvents ; i++)
	{
		double xPos		=	lineSpacing*2+lineSpacing*i-.02;
		std::stringstream stringStream;	
		stringStream << "Event " << i+1 << " Projection on Beam Line";
		G4String textString	=	stringStream.str();
		TText* eventText	=	new TText(xPos,0.04,textString);
		eventText->SetTextAngle(90);
		eventText->SetTextColor(i+2);
		eventText->SetTextSize(.03);
		eventText->Draw();
	}
}

void KSADAnalyzeVis::Legend()
{
	double height		=	0.03;
	double totalHeight	=	0;
	double verticalSpacing	=	1./(numEvents);
	for(int i = 0 ; i<numEvents ; i++)
	{
		totalHeight		=	0;

		double xStartPos        =       (eventList[i]->GetXPos())/m;
		double yStartPos        =       (eventList[i]->GetYPos())/m;
		double energyGuess	=	eventList[i]->GetEnergy()/MeV;
		double azimuthalGuess	=	eventList[i]->GetAzimuthalAngle()/deg;
		double azimuthalLow	=	eventList[i]->GetAzimuthalLow()/deg;
		double azimuthalHigh	=	eventList[i]->GetAzimuthalHigh()/deg;
		double polarGuess	=	eventList[i]->GetPolarAngle()/deg;

		double xRemainder	=	fmod(xStartPos,0.001);
		double yRemainder	=	fmod(yStartPos,0.001);
		double energyRemainder	=	fmod(energyGuess,.01);
		double azimuthalRemain	=	fmod(azimuthalGuess,.1);
		double azimuthalLRemain	=	fmod(azimuthalLow,.1);
		double azimuthalHRemain	=	fmod(azimuthalHigh,.1);
		double polarRemainder	=	fmod(polarGuess,.1);
		
		if(xRemainder >= 0.0005) xStartPos = xStartPos-xRemainder+.001;
		else xStartPos = xStartPos-xRemainder;
		if(yRemainder >= 0.0005) yStartPos = yStartPos-yRemainder+.001;
		else yStartPos = yStartPos-yRemainder;
		if(energyRemainder>=.005) energyGuess = energyGuess-energyRemainder+.01;
		else energyGuess = energyGuess-energyRemainder;
		if(azimuthalRemain>=.05) azimuthalGuess = azimuthalGuess-azimuthalRemain+.1;
		else azimuthalGuess = azimuthalGuess-azimuthalRemain;
		if(azimuthalLRemain>=.05) azimuthalLow = azimuthalLow-azimuthalLRemain+.1;
		else azimuthalLow = azimuthalLow-azimuthalLRemain;
		if(azimuthalHRemain>=.05) azimuthalHigh = azimuthalHigh-azimuthalHRemain+.1;
		else azimuthalHigh = azimuthalHigh-azimuthalHRemain;
		if(polarRemainder>=.05) polarGuess = polarGuess-polarRemainder+.1;
		else polarGuess = polarGuess-polarRemainder;

		if(azimuthalLow>180)
		{
			azimuthalLow -= 360;
			azimuthalHigh -= 360;
		}

		std::stringstream stringStream;
		stringStream << "Event " << i+1 << ":";
		G4String eventInfo	=	stringStream.str();
		stringStream.str("");

		stringStream << energyGuess << " MeV";
		G4String energyInfo	=	stringStream.str();
		stringStream.str("");

		stringStream << "Best Fit " << azimuthalGuess << "#circ, must be between " << azimuthalLow << "#circ and " << azimuthalHigh << "#circ";
		G4String azimuthalInfo	=	stringStream.str();		//accepts special root-recognized latex code.
		stringStream.str("");

		stringStream << "X = " << xStartPos*m/cm << ", Y = " << yStartPos*m/cm << " cm from beam"; 
		G4String PositionInfo	=	stringStream.str();
		stringStream.str("");
		
		stringStream << "Best Fit " << polarGuess << "#circ, must be between " << (eventList[i]->GetPolarLow())/deg << "#circ and " << (eventList[i]->GetPolarHigh())/deg << "#circ";
		G4String polarGuessInfo	=	stringStream.str();		//accepts special root-recognized latex code.
		stringStream.str("");

		double yPos		=	.97-verticalSpacing*(i);		//Each line adds its vertical height to totalheight.
		TText* event		=	new TText(0.005,yPos,eventInfo);	// titles are at .005, info title at .1, and information is at .15 pads.
		event->SetTextColor(i+2);
		event->SetTextSize(0.03);
		event->Draw();
		
		TText* energyWord	=	new TText(0.1,yPos-totalHeight,"Energy");
		energyWord->SetTextColor(0);
		energyWord->SetTextSize(0.03);
		energyWord->Draw();

		TText* energy		=	new TText(0.25,yPos-totalHeight,energyInfo);
		energy->SetTextColor(0);
		energy->SetTextSize(0.03);
		totalHeight		=	totalHeight+height;
		energy->Draw();

		TText* positionWord	=	new TText(0.1,yPos-totalHeight,"Position");
		positionWord->SetTextColor(0);
		positionWord->SetTextSize(0.03);
		positionWord->Draw();
		
		TText* Position		=	new TText(0.25,yPos-totalHeight,PositionInfo);
		Position->SetTextColor(0);
		Position->SetTextSize(0.03);
		totalHeight		=	totalHeight+height;
		Position->Draw();

		TText* azimuthalWord	=	new TText(0.1,yPos-totalHeight,"Azimuthal");
		azimuthalWord->SetTextColor(0);
		azimuthalWord->SetTextSize(0.03);
		azimuthalWord->Draw();

		TLatex* azimuthal	=	new TLatex(0.25,yPos-totalHeight,azimuthalInfo);
		azimuthal->SetTextColor(0);
		azimuthal->SetTextSize(0.03);
		totalHeight		=	totalHeight+height;
		azimuthal->Draw();

		TText* polarWord	=	new TText(0.1,yPos-totalHeight,"Polar");
		polarWord->SetTextColor(0);
		polarWord->SetTextSize(0.03);
		polarWord->Draw();

		TLatex* polar		=	new TLatex(0.25,yPos-totalHeight,polarGuessInfo);
		polar->SetTextColor(0);
		polar->SetTextSize(0.03);
		totalHeight		=	totalHeight+height;
		polar->Draw();

		TText* messageWord	=	new TText(0.1,yPos-totalHeight,"Event Msg");
		messageWord->SetTextColor(0);
		messageWord->SetTextSize(0.03);
		messageWord->Draw();

		TText* message          =       new TText(0.25,yPos-totalHeight,eventList[i]->GetMsg());
		message->SetTextColor(0);
		message->SetTextSize(0.03);
		totalHeight             =       totalHeight+height;
		message->Draw();
	}
}
